package com.mlx.mbg.code.method;

import com.mlx.mbg.code.MbgUtil;
import com.mlx.mbg.code.inter.EnableMethod;
import com.mlx.mbg.code.config.MbgPropertyConfig;
import com.mlx.mbg.code.inter.ExtensionLevel;
import com.mlx.mbg.code.inter.IExtensionMethod;
import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.JavaVisibility;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.Parameter;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.Collections;
import java.util.List;

@EnableMethod
public class UpdateBatchMethod implements IExtensionMethod {

    @Override
    public boolean checkConfig(ExtensionLevel level, MbgPropertyConfig mbgPropertyConfig, IntrospectedTable introspectedTable) {
        return getExtensionLevelSet().contains(level) && mbgPropertyConfig.getEnableUpdateBatch() && MbgUtil.checkPrimaryKey(introspectedTable, "updateBatch");
    }

    @Override
    public int getOrder() {
        return 500;
    }

    @Override
    public List<Method> buildMethod(IntrospectedTable introspectedTable) {
        JavaVisibility methodVisibility = JavaVisibility.PUBLIC;

        // 设置返回类型是List
        FullyQualifiedJavaType methodReturnType = new FullyQualifiedJavaType("int");

        String methodName = "updateBatch";

        // 设置参数类型
        FullyQualifiedJavaType methodParameterType = new FullyQualifiedJavaType("Collection");
        //给参数类型补充泛型
        methodParameterType.addTypeArgument(new FullyQualifiedJavaType(introspectedTable.getBaseRecordType()));
        // 方法参数
        Parameter methodParameter = new Parameter(methodParameterType, "dataCollection");

        Method method = new Method();
        method.setVisibility(methodVisibility);
        method.setReturnType(methodReturnType);
        method.setName(methodName);
        method.addParameter(methodParameter);
        // 设置备注
        method.addJavaDocLine("/**");
        method.addJavaDocLine(" * 批量修改：数据为空会报错，使用时请判断是否空");
        method.addJavaDocLine(" */");

        return Collections.singletonList(method);
    }

    @Override
    public List<XmlElement> buildSQL(IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime();
        List<IntrospectedColumn> keyColumnList = introspectedTable.getPrimaryKeyColumns();

        XmlElement foreach = new XmlElement("foreach");
        foreach.addAttribute(new Attribute("collection", "dataCollection"));
        foreach.addAttribute(new Attribute("item", "data"));
        foreach.addAttribute(new Attribute("separator", ";"));

        TextElement text1 = new TextElement(  "update " + introspectedTable.getFullyQualifiedTableNameAtRuntime());
        XmlElement set = new XmlElement("set");
        XmlElement includeProperty = new XmlElement("include");
        includeProperty.addAttribute(new Attribute("refid", "Update_Selective_Property_List"));
        set.addElement(includeProperty);

        StringBuilder stringBuilder = new StringBuilder("where ");
        int size = keyColumnList.size();
        int maxIndex = size - 1;
        for (int i = 0; i < size ; i++){
            IntrospectedColumn column = keyColumnList.get(0);
            String actualColumnName = column.getActualColumnName();
            String javaProperty = column.getJavaProperty();
            String jdbcTypeName = column.getJdbcTypeName();

            if (i != maxIndex){
                stringBuilder.append(actualColumnName).append(" = ").append("#{data.").append(javaProperty).append(",jdbcType=").append(jdbcTypeName).append("} and ");
            }else {
                stringBuilder.append(actualColumnName).append(" = ").append("#{data.").append(javaProperty).append(",jdbcType=").append(jdbcTypeName).append("}");
            }
        }
        TextElement text2 = new TextElement(stringBuilder.toString());

        foreach.addElement(text1);
        foreach.addElement(set);
        foreach.addElement(text2);

        XmlElement updateBatch = new XmlElement("update");
        updateBatch.addAttribute(new Attribute("id", "updateBatch"));

        updateBatch.addElement(foreach);

        return Collections.singletonList(updateBatch);
    }
}
